package com.utils;

import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import org.apache.commons.lang.StringUtils;

import com.bean.PayJson;
import com.bean.PayNo;
import com.bean.ReFundRequest;
import com.bean.WxPayDto;
import com.config.WeChatConfig;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ophiux.wechat.model.OrderQueryResponse;
import com.ophiux.wechat.model.ReFundResponse;
import com.ophiux.wechat.model.Refund;
import com.ophiux.wechat.utils.Sha1Util;
import com.ophiux.wechat.utils.TenpayUtil;
import com.utils.http.HttpConnect;
import com.utils.http.HttpResponse;

import net.sf.json.JSONObject;


/**
 * @author zengjian
 * 
 */
public class PayUtils {
	//微信支付商户开通后 微信会提供appid和appsecret和商户号partner
	private static String appid = "wxb50d6933834082a6";
	private static String appsecret = "6db565d53343acdf96dd2fa2b4f38ebd";
	private static String partner = "1327201101";
	//这个参数partnerkey是在商户后台配置的一个32位的key,微信商户平台-账户设置-安全设置-api安全
	private static String partnerkey = "cb8sq7qievtp9fs8juyz1ids5eohkq5w";
	
	/**
	 * 获取微信扫码支付二维码连接
	 */
	public static String getCodeurl(WxPayDto tpWxPayDto){
		// 订单号
		String orderId = tpWxPayDto.getOrderId();
		// 附加数据 原样返回
		String attach = tpWxPayDto.getUserID();
		// 总金额以分为单位，不带小数点
		String totalFee = getMoney(tpWxPayDto.getTotalFee());
		// 订单生成的机器 IP
		String spbill_create_ip = tpWxPayDto.getSpbillCreateIp();
		// 这里notify_url是 支付完成后微信发给该链接信息，可以判断会员是否支付成功，改变订单状态等。
		String notify_url = tpWxPayDto.getNotifyUrl();
		String trade_type = "NATIVE";
		// 商户号
		String mch_id = partner;
		//子商户号
		String sub_mch_id=tpWxPayDto.getSubMchid();
		// 随机字符串
		String nonce_str = getNonceStr();
		// 商品描述根据情况修改
		String body = tpWxPayDto.getBody();
		// 商户订单号
		String out_trade_no = orderId;

		SortedMap<String, String> packageParams = new TreeMap<String, String>();
		packageParams.put("appid", appid);
		packageParams.put("mch_id", mch_id);
		packageParams.put("sub_mch_id", sub_mch_id);
		packageParams.put("nonce_str", nonce_str);
		packageParams.put("body", body);
		packageParams.put("attach", attach);
		packageParams.put("out_trade_no", out_trade_no);

		// 这里写的金额为1 分到时修改
		packageParams.put("total_fee", totalFee);
		packageParams.put("spbill_create_ip", spbill_create_ip);
		packageParams.put("notify_url", notify_url);
		packageParams.put("trade_type", trade_type);

		RequestHandler reqHandler = new RequestHandler(null, null);
		reqHandler.init(appid, appsecret, partnerkey);

		String sign = reqHandler.createSign(packageParams);
		String xml = "<xml>" + "<appid>" + appid + "</appid>" + "<mch_id>"
				+ mch_id + "</mch_id>" + "<sub_mch_id>"
				+ sub_mch_id + "</sub_mch_id>"+ "<nonce_str>" + nonce_str
				+ "</nonce_str>" + "<sign>" + sign + "</sign>"
				+ "<body><![CDATA[" + body + "]]></body>" 
				+ "<out_trade_no>" + out_trade_no
				+ "</out_trade_no>" + "<attach>" + attach + "</attach>"
				+ "<total_fee>" + totalFee + "</total_fee>"
				+ "<spbill_create_ip>" + spbill_create_ip
				+ "</spbill_create_ip>" + "<notify_url>" + notify_url
				+ "</notify_url>" + "<trade_type>" + trade_type
				+ "</trade_type>" + "</xml>";
		String code_url = "";
		String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
		code_url = new GetWxOrderno().getCodeUrl(createOrderURL, xml);
		System.out.println("code_url----------------"+code_url);
		return code_url;
	}
	
	/**
	 * 查询订单
	 */
	public static String getOrderQuery(String orderNo,String subMchId){
		// 商户号
		String mch_id = WeChatConfig.MACH_ID;
		//子商户号
		String sub_mch_id=subMchId;
		// 随机字符串
		String nonce_str = getNonceStr();
		// 商户订单号
		//String out_trade_no = "9001201606011217047";
		String out_trade_no = orderNo;

		SortedMap<String, String> packageParams = new TreeMap<String, String>();
		packageParams.put("appid", WeChatConfig.APP_ID);
		packageParams.put("mch_id", mch_id);
		//packageParams.put("sub_mch_id", sub_mch_id);
		packageParams.put("nonce_str", nonce_str);
		packageParams.put("out_trade_no", out_trade_no);
		RequestHandler reqHandler = new RequestHandler(null, null);
		reqHandler.init(WeChatConfig.APP_ID, WeChatConfig.APP_SECRET, WeChatConfig.API_TOKEN);
		String sign = reqHandler.createSign(packageParams);
		String xml = "<xml>" + 
		        "<appid>" + WeChatConfig.APP_ID + "</appid>" + 
				"<mch_id>"+ mch_id + "</mch_id>" + 
				"<nonce_str>" + nonce_str+ "</nonce_str>" + 
		        "<sign>" + sign + "</sign>"+ 
				"<out_trade_no>" + out_trade_no+ "</out_trade_no>"+ 
		        "</xml>";
		OrderQueryResponse order=new OrderQueryResponse();
		String createOrderURL = "https://api.mch.weixin.qq.com/pay/orderquery";
		order = new GetWxOrderno().getOrderQu(createOrderURL, xml);
		String orderNO="";
		ObjectMapper obj=new ObjectMapper();
		try {
			orderNO=obj.writeValueAsString(order);
			System.out.println("查询订单返回:"+obj.writeValueAsString(order));
		} catch (Exception e) {
			e.printStackTrace();
		} 
		return orderNO;
	}
	
	/**
	 * 退款
	 */
	public static String getRefund(ReFundRequest refund){
		// 商户号
		String mch_id = WeChatConfig.MACH_ID;
		//子商户号
		String sub_mch_id=refund.getSub_mch_id();
		// 随机字符串
		String nonce_str = getNonceStr();
		// 商户订单号
		String out_trade_no =refund.getOut_trade_no();
		//String out_trade_no = orderNo;
		
		//操作员帐号, 默认为商户号 
		//String op_user_id=refund.getOut_trade_no();
		String op_user_id=mch_id;  //陈辉
		//商户系统内部的退款单号，商户系统内部唯一，同一退款单号多次请求只退一笔 
		String out_refund_no=refund.getOut_refund_no();
		//退款金额 
		String refund_fee=refund.getRefund_fee();
		//总金额 
		String total_fee=refund.getTotal_fee();

		SortedMap<String, String> packageParams = new TreeMap<String, String>();
		packageParams.put("appid", WeChatConfig.APP_ID);
		packageParams.put("mch_id", mch_id);
		//packageParams.put("sub_mch_id", sub_mch_id);
		packageParams.put("nonce_str", nonce_str);
		packageParams.put("op_user_id", op_user_id);
		packageParams.put("out_refund_no", out_refund_no);
		packageParams.put("refund_fee", refund_fee);
		packageParams.put("total_fee", total_fee);
		packageParams.put("out_trade_no", out_trade_no);
		RequestHandler reqHandler = new RequestHandler(null, null);
		reqHandler.init(WeChatConfig.APP_ID, WeChatConfig.APP_SECRET, WeChatConfig.API_TOKEN);
		String sign = reqHandler.createSign(packageParams);
		String xml = "<xml>" + 
		        "<appid>" + WeChatConfig.APP_ID + "</appid>" + 
				"<mch_id>"+ mch_id + "</mch_id>" + 
				"<nonce_str>" + nonce_str+ "</nonce_str>" + 
				"<op_user_id>" + op_user_id+ "</op_user_id>" +
				"<out_refund_no>" + out_refund_no+ "</out_refund_no>" +
				"<out_trade_no>" + out_trade_no+ "</out_trade_no>" +
				"<refund_fee >" + refund_fee + "</refund_fee >" +
				"<total_fee >" + total_fee + "</total_fee >" +
		        "<sign>" + sign + "</sign>"+ 
		        "</xml>";
		Refund reFund=new Refund();
		String createOrderURL = "https://api.mch.weixin.qq.com/secapi/pay/refund";
		reFund = new GetWxOrderno().getWxRefund(createOrderURL, xml);
		String reFundMessage="";
		ReFundResponse message=new ReFundResponse();
		try {
			if(StringUtils.isNotBlank(reFund.getErr_code_des())){
				ObjectMapper obj=new ObjectMapper();
				message.setMessage(reFund.getErr_code_des());
				message.setStatus("0");
				reFundMessage=obj.writeValueAsString(message);
			}else{
				ObjectMapper obj=new ObjectMapper();
				message.setMessage("退款成功！");
				message.setStatus("200");
				message.setRefund(reFund);
				reFundMessage=obj.writeValueAsString(message);
				System.out.println("退款返回:"+obj.writeValueAsString(reFund));
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} 
		return reFundMessage;
	}
	
	
	
	/**
	 * 获取请求预支付id报文
	 * @return
	 */
	@SuppressWarnings("static-access")
	public static PayJson getPackage(WxPayDto tpWxPayDto) {
		String code=tpWxPayDto.getCode();
		//授权成功获取openId
		String openId ="";
		/**
		 * 获取用户信息-openId微信的URL地址
		 */
		String URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="
						+WeChatConfig.APP_ID+"&secret="+WeChatConfig.APP_SECRET+"" +
								"&code="+code+"&grant_type=authorization_code";
		Map<String, Object> dataMap = new HashMap<String, Object>();
		//https请求发起
		HttpResponse temp = HttpConnect.getInstance().doGetStr(URL);		
		String tempValue="";
		if( temp == null){
		}else
		{
			try {
				tempValue = temp.getStringResult();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			JSONObject  jsonObj = JSONObject.fromObject(tempValue);
			if(jsonObj.containsKey("errcode")){
				System.out.println(tempValue);
			}
			openId = jsonObj.getString("openid");
		}
		System.out.println("openId=========="+openId);
		// 订单号
		String orderId = tpWxPayDto.getOrderId();
		// 附加数据 原样返回
		String attach = tpWxPayDto.getUserID();
		// 总金额以分为单位，不带小数点
		//String totalFee = getMoney(tpWxPayDto.getTotalFee());
		String totalFee =tpWxPayDto.getTotalFee();
		// 订单生成的机器 IP
		String spbill_create_ip = tpWxPayDto.getSpbillCreateIp();
		// 这里notify_url是 支付完成后微信发给该链接信息，可以判断会员是否支付成功，改变订单状态等。
		String notify_url =tpWxPayDto.getNotifyUrl();
		//String notify_url="http://taurus.ophiux.com/TlsWeiChatpay/notifyServlet";
		String trade_type = "JSAPI";
		// 商户号
		//String mch_id = partner;
		//子商户号
		String sub_mch_id=tpWxPayDto.getSubMchid();
		// 随机字符串
		String nonce_str = getNonceStr();
		// 商品描述根据情况修改
		String body = tpWxPayDto.getBody();
		// 商户订单号
		String out_trade_no = orderId;

		SortedMap<String, String> packageParams = new TreeMap<String, String>();
		packageParams.put("appid", WeChatConfig.APP_ID);
	//	packageParams.put("mch_id", mch_id);
		packageParams.put("mch_id", sub_mch_id);
		packageParams.put("nonce_str", nonce_str);
		packageParams.put("body", body);
		packageParams.put("attach", attach);
		packageParams.put("out_trade_no", out_trade_no);

		// 这里写的金额为1 分到时修改
		packageParams.put("total_fee", totalFee);
		packageParams.put("spbill_create_ip", spbill_create_ip);
		packageParams.put("notify_url", notify_url);

		packageParams.put("trade_type", trade_type);
		packageParams.put("openid", openId);

		RequestHandler reqHandler = new RequestHandler(null, null);
	//	reqHandler.init(appid, appsecret, partnerkey);
		reqHandler.init(WeChatConfig.APP_ID, WeChatConfig.APP_SECRET, 
				WeChatConfig.API_TOKEN);

		String sign = reqHandler.createSign(packageParams);
		String xml = "<xml>" + "<appid>" + WeChatConfig.APP_ID + "</appid>" + "<mch_id>"
				+ sub_mch_id + "</mch_id>"
			    + "<nonce_str>" + nonce_str
				+ "</nonce_str>" + "<sign>" + sign + "</sign>"
				+ "<body><![CDATA[" + body + "]]></body>" 
				+ "<out_trade_no>" + out_trade_no
				+ "</out_trade_no>" + "<attach>" + attach + "</attach>"
				+ "<total_fee>" + totalFee + "</total_fee>"
				+ "<spbill_create_ip>" + spbill_create_ip
				+ "</spbill_create_ip>" + "<notify_url>" + notify_url
				+ "</notify_url>" + "<trade_type>" + trade_type
				+ "</trade_type>" + "<openid>" + openId + "</openid>"
				+ "</xml>";
		
		String prepay_id = "";
		String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
		PayNo payNo = new GetWxOrderno().getPayNo(createOrderURL, xml);
		System.out.println("获取到的预支付ID：" + payNo.getPrepayId());
		prepay_id=payNo.getPrepayId();
		PayJson pay=new PayJson();
		if(StringUtils.isNotBlank(prepay_id)){
			//获取prepay_id后，拼接最后请求支付所需要的package
			SortedMap<String, String> finalpackage = new TreeMap<String, String>();
			String timestamp = Sha1Util.getTimeStamp();
			String packages = "prepay_id="+payNo.getPrepayId();
			finalpackage.put("appId", WeChatConfig.APP_ID);  
			finalpackage.put("timeStamp", timestamp);  
			finalpackage.put("nonceStr", nonce_str);  
			finalpackage.put("package", packages);  
			finalpackage.put("signType", "MD5");
			//要签名
			String finalsign = reqHandler.createSign(finalpackage);
			pay.setAppId(WeChatConfig.APP_ID);
			pay.setNonceStr(nonce_str);
			pay.setPackages(packages);
			pay.setTimeStamp(timestamp);
			pay.setSign(finalsign);
			pay.setSignType("MD5");
			pay.setMessage("预支付订单下单成功!");
		}else{
			pay.setMessage(payNo.getErrCodeDes());
		}
			
		return pay;
	}
	
	
	/**
	 * 获取openId
	 */
	public static String getOpenId(String code){
		String openId ="";
		String URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+appid+"&secret="+appsecret+"&code="+code+"&grant_type=authorization_code";
		Map<String, Object> dataMap = new HashMap<String, Object>();
		HttpResponse temp = HttpConnect.getInstance().doGetStr(URL);		
		String tempValue="";
		if( temp == null){
		}else
		{
			try {
				tempValue = temp.getStringResult();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			JSONObject  jsonObj = JSONObject.fromObject(tempValue);
			if(jsonObj.containsKey("errcode")){
				System.out.println(tempValue);
			}
			openId = jsonObj.getString("openid");
		}
		System.out.println("openId=========="+openId);
		return openId;
	}

	/**
	 * 获取随机字符串
	 * @return
	 */
	public static String getNonceStr() {
		// 随机数
		String currTime = TenpayUtil.getCurrTime();
		// 8位日期
		String strTime = currTime.substring(8, currTime.length());
		// 四位随机数
		String strRandom = TenpayUtil.buildRandom(4) + "";
		// 10位序列号,可以自行调整。
		return strTime + strRandom;
	}

	/**
	 * 元转换成分
	 * @param money
	 * @return
	 */
	public static String getMoney(String amount) {
		if(amount==null){
			return "";
		}
		// 金额转化为分为单位
		String currency =  amount.replaceAll("\\$|\\￥|\\,", "");  //处理包含, ￥ 或者$的金额  
        int index = currency.indexOf(".");  
        int length = currency.length();  
        Long amLong = 0l;  
        if(index == -1){  
            amLong = Long.valueOf(currency+"00");  
        }else if(length - index >= 3){  
            amLong = Long.valueOf((currency.substring(0, index+3)).replace(".", ""));  
        }else if(length - index == 2){  
            amLong = Long.valueOf((currency.substring(0, index+2)).replace(".", "")+0);  
        }else{  
            amLong = Long.valueOf((currency.substring(0, index+1)).replace(".", "")+"00");  
        }  
        return amLong.toString(); 
	}

}
